package de.lazy.gui.multifile;

import javax.swing.JFrame;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Properties;

import javax.swing.BorderFactory;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JButton;
import javax.swing.border.EtchedBorder;

import de.lazy.gui.components.DraggableTabbedPane;

public class MultiFileFrame extends JFrame {

	private static final String OPEN_FILE_BUTTON_CAPTION = "Open file";
	private static final Dimension START_SIZE = new Dimension(1000, 600);
	
	private static final String DIALOG_WORKPATH_PROPERTY = "dialog_workpath";
	private static final String DIALOG_WIDTH_PROPERTY = "dialog_width";
	private static final String DIALOG_HEIGHT_PROPERTY = "dialog_height";
	
	private DraggableTabbedPane tabbedPane;
	private JFileChooser fileChooser;
	private ArrayList<FileOpenedListener> fileOpenendListener;
	private JPanel startPanel;

	private OutputStream propertiesOutputStream; 
	private Properties dialogProperties;
	
	public MultiFileFrame(JPanel startPanel) {
		fileChooser = new JFileChooser();
		fileOpenendListener = new ArrayList<FileOpenedListener>(); //java6 syntax for safety :)
		this.startPanel = startPanel;
		
		dialogProperties = new Properties();
		propertiesOutputStream = null;
		
		setPreferredSize(START_SIZE);
		setVisible(true);
		getContentPane().setLayout(new BorderLayout(0, 0));
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		tabbedPane = new DraggableTabbedPane();
		getContentPane().add(tabbedPane, BorderLayout.CENTER);
		
		
		addWindowListener(new java.awt.event.WindowAdapter() {
		    @Override
		    public void windowClosing(java.awt.event.WindowEvent windowEvent) {
				if(propertiesOutputStream != null){
					
					try {
						dialogProperties.put(DIALOG_HEIGHT_PROPERTY, new Double (MultiFileFrame.this.getSize().getHeight()).toString());
						dialogProperties.put(DIALOG_WIDTH_PROPERTY, new Double (MultiFileFrame.this.getSize().getWidth()).toString());
						dialogProperties.store(propertiesOutputStream,null);
						
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				//System.exit(0);
		    }
		});
		
		createOpenTab();
		pack();
	}

	public MultiFileFrame(JPanel startPanel,Properties dialogProperties){
		this(startPanel);
		this.dialogProperties = dialogProperties;
		
		if(dialogProperties.containsKey(DIALOG_WORKPATH_PROPERTY)){
			fileChooser.setCurrentDirectory(new File(dialogProperties.getProperty(DIALOG_WORKPATH_PROPERTY)));
		}
		if(dialogProperties.containsKey(DIALOG_WIDTH_PROPERTY) && dialogProperties.containsKey(DIALOG_HEIGHT_PROPERTY)){
			
			try{
				System.out.println("== Dialog properties:");
				System.out.println("width '"+dialogProperties.get(DIALOG_WIDTH_PROPERTY)+"'");
				System.out.println("height '"+dialogProperties.get(DIALOG_HEIGHT_PROPERTY)+"'");
				double width = Double.parseDouble((String) dialogProperties.get(DIALOG_WIDTH_PROPERTY));
				double height = Double.parseDouble((String) dialogProperties.get(DIALOG_HEIGHT_PROPERTY));
				
				setPreferredSize(new Dimension((int)width, (int)height));
				pack();
			}
			catch(Exception e){
				e.printStackTrace();
			}
		 
		}
		else{
			System.out.println("No dialog width or height defined in properties, loading default.");
		}
	}

	public void setDialogPropertiesOutputStream(OutputStream os){
		propertiesOutputStream = os;
	}
	
	private void createOpenTab() {
		// create the open button
		JButton openButton = new JButton(OPEN_FILE_BUTTON_CAPTION);
		openButton.setOpaque(false);
		//openButton.setPreferredSize(new Dimension(50, 20));
		openButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				int returnVal = fileChooser.showOpenDialog(tabbedPane);

				if (returnVal == JFileChooser.APPROVE_OPTION) {
					fileOpenendAction(fileChooser.getSelectedFile());
				}
			}
		});

		tabbedPane.addComponentTab(openButton, startPanel);

	}

	public void addTab(String title, Component component) {

		
		tabbedPane.addTab(title, component);
		final int index = tabbedPane.indexOfTab(title);

		JPanel pnlTab = new JPanel();
		pnlTab.setOpaque(false);

		JLabel lblTitle = new JLabel(title);
		pnlTab.add(lblTitle);

		JButton btnClose = new JButton(" X ");
		btnClose.setContentAreaFilled(false);
		btnClose.setFocusPainted(false);
		btnClose.setOpaque(false);
		btnClose.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));

		pnlTab.add(btnClose);

		tabbedPane.setTabComponentAt(index, pnlTab);

		btnClose.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				tabbedPane.removeTabAt(index);
			}
		});

		tabbedPane.setSelectedIndex(index);
	}

	public void addFileOpenedLister(FileOpenedListener listener){
		fileOpenendListener.add(listener);
	}
	
	public void fileOpenendAction(File selectedFile) {
		String title = selectedFile.getName();
		
		//only add the new tab if file isnt openend yet
		if(tabbedPane.indexOfTab(title) == -1){
			JPanel container = new JPanel();
			addTab(title, container);
			
			for(FileOpenedListener listener : fileOpenendListener){
				listener.opened(selectedFile, container);
			}
		}
		else{
			//file already opened, select the tab
			tabbedPane.setSelectedIndex(tabbedPane.indexOfTab(title));
		}
		
		dialogProperties.put(DIALOG_WORKPATH_PROPERTY, selectedFile.getAbsolutePath());
		if(propertiesOutputStream != null){
			
			try {
				dialogProperties.store(propertiesOutputStream,null);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}		

	}

}
